/*
 * Resolver.java    0.0.1    08/dic/2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */ 
package org.mentalsmash.tazio.transparency.interfaces;

import java.net.InetAddress;
import java.util.List;

import org.mentalsmash.tazio.commons.identifiers.NID;
import org.mentalsmash.tazio.net.cs.client.Connection;
import org.mentalsmash.tazio.transparency.impl.TransparentDeliveryException;

/**
 * A Resolver object has the task of resolving the mappings from a {@link NID} and 
 * the corresponding {@link InetAddress}. When a component of upper layers will have to send 
 * a message to a recipient, identified by its {@link NID}, it will communicate with 
 * this component, which will take the {@link NID} as an input parameter and will 
 * return the actual address of the destination.
 * <p>
 * This component will be used both on WeakReplicaManagers and on ReplicaManagers.
 * </p>
 * 
 * @version 0.0.1	08/dic/2009
 * @author Enrico Savioli <savioli.enrico@gmail.com>
 */
public interface Resolver {

	/**
	 * This method returns a {@link List} containing the {@link NID}s of 
	 * <strong>all</strong> the Replica Managers connected together if it is invoked 
	 * at WeakReplicaManager side. Otherwise, if called at ReplicaManager side, it 
	 * returns a {@link List} of all the WeakReplicaManagers connected to it.
	 * 
	 * @return	a {@link List} containing the {@link NID}s of all the RMs.
	 */
	List<NID> getNIDList();
	
//	/**
//	 * This method returns a {@link List} containing only the {@link NID} of the 
//	 * ReplicaManager to which the system is currently connected.
//	 * <p>
//	 * The method returns a {@link List} even if it contains only an element, this is done 
//	 * because we want a {@link Deliverer} to be created with a {@link List} as a 
//	 * construction parameter, without having to distinguish the cases of a list of servers 
//	 * and a recipient only. 
//	 * </p>
//	 * 
//	 * @return	a {@link List} containing the {@link NID} of the Replica Manager 
//	 * 			to which the client is connected.
//	 */
//	List<NID> getCurrentServer();
	
	/**
	 * This method has to be invoked every time a message has to be sent, by invoking it with
	 * a {@link NID} as an input parameter, the Resolver will find a match between 
	 * the supplied id and an {@link InetAddress}, corresponding to the address where the 
	 * node identified by the input {@link NID} can be reached.
	 *  
	 * @param NID					the {@link NID} of the node whose address 
	 * 								has to be retrieved.
	 * @return						the {@link Connection} where the node can be reached.
	 * @throws TransparentDeliveryException		thrown when the resolver failed in connecting to the 
	 * 								remote Replica Manager, thus it means that the server 
	 * 								is temporarily unavailable.	
	 */
	Connection resolve(NID nid) throws TransparentDeliveryException;
	
	/**
	 * This method will add an entry to the implementation specific object which stores the 
	 * mappings between the {@link NID}s and the corresponding {@link InetAddress}.
	 * <p>
	 * This method could be used if we want a WeakReplicaManager to be informed of the 
	 * members of the cluster of ReplicaManagers every time it connects to a ReplicaManager 
	 * and to fill the entries of the Resolver on its own.
	 * </p>
	 * <p>
	 * This will also be used when a WeakReplicaManager connects to a ReplicaManager, the 
	 * latter one will add the mapping of the WRM in order to be able to communicate with 
	 * it.
	 * </p>
	 * 
	 * @param NID		the {@link NID} of the node for which a new mapping has to 
	 * 					be added.
	 * @param address	the {@link InetAddress} of the node for which a new mapping has to 
	 * 					be added.
	 */
	void registerMapping(NID nid, InetAddress address);
	
	/**
	 * This method will remove an entry from the implementation-specific object which stores 
	 * the mappings between the {@link NID}s and the corresponding {@link InetAddress}
	 * if the mapping exists, otherwise it will do nothing.
	 * 
	 * @param NID		the {@link NID} of the node for which the mapping has to be
	 * 					removed.
	 * @param address	the {@link InetAddress} of the node for which the mapping has to be
	 * 					removed.
	 */
	void removeMapping(NID nid);
	
	InetAddress getAddress(NID nid);
	
	/**
	 * Used to make the resolver use the actual listening addres of the WRM when building
	 * BeginConnectionMessage-s
	 * @param address
	 * @param port
	 */
	void setLocalListeningAddress(InetAddress address, int port);
	
}
